﻿using System;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
using System.Runtime.Remoting.Messaging;
using StockTrader.FrontEnd.MarketViewer.DAL;
using StockTrader.FrontEnd.DataContract;

namespace StockTrader.FrontEnd.MarketViewer.BusinessLogic
{
    public class AsyncDataProcessor
    {
        private int _firmno;
        private DateTime _transdate;
        private string _pcflag;
        private string _orderside;
        private string _symbol;
        private int _volume;
        private int _matched;
        private int _price;
        private int _time;
        private string _accountno;

        private InsertRecord _invokeMe;
        private ProgressBar _progress;
        private Label _elapsed;
        private Label _remain;
        private Label _speed;
        private Label _percent;
        private Label _status;

        private Label _current;
        private int _numOfRecord;

        private DateTime _startTime;
        private int _totalRecord;

        private delegate void InsertRecord(int firmno, DateTime transdate, string pcflag, string orderside, string symbol, int volume, int matched, int price, int time, string accountno);

        public AsyncDataProcessor(int firmno, DateTime transdate, string pcflag, string orderside, string symbol, int volume, int matched, int price, int time, string accountno, ProgressBar progress, Label current, int numofrecord, DateTime starttime, int totalrecord, Label elapsed, Label remain, Label speed, Label percent, Label status)
        {
            _firmno = firmno;
            _transdate = transdate;
            _pcflag = pcflag;
            _orderside = orderside;
            _symbol = symbol;
            _volume = volume;
            _matched = matched;
            _price = price;
            _time = time;
            _accountno = accountno;

            _progress = progress;
            _current = current;
            _numOfRecord = numofrecord;
            _startTime = starttime;
            _totalRecord = totalrecord;
            _elapsed = elapsed;
            _remain = remain;
            _speed = speed;
            _percent = percent;
            _status = status;

            _invokeMe = new InsertRecord(DataAccess.InsertDailyOrderWithAccountNo);
        }

        public void Execute()
        {
            try
            {
                //Update UI here
                _invokeMe.BeginInvoke(_firmno, _transdate, _pcflag, _orderside, _symbol, _volume, _matched, _price, _time, _accountno, this.CallBack, null);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
        private void CallBack(IAsyncResult ar)
        {
            try
            {
                AsyncResult result = (AsyncResult)ar;
                // grab the delegate
                InsertRecord del = (InsertRecord)result.AsyncDelegate;

                del.EndInvoke(ar);
                //Update UI here

                MethodInvoker updateUI = delegate
                {
                    int completed = Convert.ToInt32(_numOfRecord * 100.0 / _totalRecord);
                    _progress.Value = _numOfRecord;
                    _current.Text = _numOfRecord.ToString("N0");
                    _percent.Text = completed.ToString("N0");
                    if (completed.Equals(100))
                        _status.Text = "Đã cập nhật xong " + _numOfRecord.ToString() + " dòng.";
                };
                if (_progress.InvokeRequired || _current.InvokeRequired ||
                    _percent.InvokeRequired || _status.InvokeRequired)
                {
                    _progress.Invoke(updateUI);
                    _current.Invoke(updateUI);
                    _percent.Invoke(updateUI);
                    _status.Invoke(updateUI);
                }
                else
                    updateUI();

                MethodInvoker TimeRelatedParam = delegate
                {
                    TimeSpan execTime = DateTime.Now - _startTime;
                    int speed = Convert.ToInt32(_numOfRecord / execTime.TotalSeconds + 1);
                    _elapsed.Text = execTime.Minutes.ToString("00") + " : " +
                                    execTime.Seconds.ToString("00") + " : " +
                                    execTime.Milliseconds.ToString("00");

                    _speed.Text = speed.ToString();
                    TimeSpan estimateExec = new TimeSpan(0, 0, Convert.ToInt32((_totalRecord - _numOfRecord) / speed));
                    _remain.Text = estimateExec.Minutes.ToString("00") + " : " +
                                    estimateExec.Seconds.ToString("00") + " : " +
                                    estimateExec.Milliseconds.ToString("00"); ;

                };
                if (_elapsed.InvokeRequired || _remain.InvokeRequired || _speed.InvokeRequired)
                {
                    _elapsed.Invoke(TimeRelatedParam);
                    _remain.Invoke(TimeRelatedParam);
                    _speed.Invoke(TimeRelatedParam);
                }
                else
                    TimeRelatedParam();
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
        }
    }
}
